package com.atguigu.gmall.activity.controller;

import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.common.util.MD5;
import com.atguigu.gmall.model.activity.OrderRecode;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.client.OrderFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author Fxz
 * @version 1.0
 * @date 2022-02-25 16:18
 */
@SuppressWarnings("all")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/activity/seckill")
public class SeckillGoodsApiController {

	private final RabbitService rabbitService;

	private final OrderFeignClient orderFeignClient;

	private final UserFeignClient userFeignClient;

	private final SeckillGoodsService seckillGoodsService;

	private final RedisTemplate redisTemplate;

	/**
	 * 查询所有秒杀商品
	 */
	@GetMapping("/findAll")
	public Result<List<SeckillGoods>> findAll() {
		return Result.ok(seckillGoodsService.findAll());
	}

	/**
	 * 根据skuId查询秒杀商品
	 */
	@GetMapping("/getSeckillGoods/{skuId}")
	public Result<SeckillGoods> getSeckillGoods(@PathVariable("skuId") Long skuId) {
		return Result.ok(seckillGoodsService.findSeckillGoodsById(skuId));
	}

	/**
	 * 获取下单码
	 */
	@GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
	public Result getSeckillSkuIdStr(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
		SeckillGoods goods = seckillGoodsService.findSeckillGoodsById(skuId);
		String userId = AuthContextHolder.getUserId(request);
		if (StringUtils.isNotBlank(userId)) {
			Date currentTime = new Date();
			// 当前时间是否再秒杀时间内
			if (DateUtil.dateCompare(goods.getStartTime(), currentTime)
					&& DateUtil.dateCompare(currentTime, goods.getEndTime())) {
				String skuIdStr = MD5.encrypt(userId.toString());
				return Result.ok(skuIdStr);
			}
		}
		return Result.fail();
	}

	/**
	 * 秒杀下单
	 */
	@PostMapping("/auth/seckillOrder/{skuId}")
	public Result seckillOrder(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
		String skuIdStr = request.getParameter("skuIdStr");
		// 比较下单码
		if (!MD5.encrypt(AuthContextHolder.getUserId(request)).equals(skuIdStr)) {
			return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
		}
		// 校验状态位
		String state = (String) CacheHelper.get(skuId.toString());
		if (StringUtils.isBlank(state)) {
			return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
		}
		else if ("0".equals(state)) {
			return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
		}
		else if ("1".equals(state)) {
			// 可以下单
			UserRecode userRecode = UserRecode.builder().userId(AuthContextHolder.getUserId(request)).skuId(skuId)
					.build();
			// 发送消息到rabbitmq
			rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SECKILL_USER, MqConst.ROUTING_SECKILL_USER, userRecode);
		}
		return Result.ok();
	}

	/**
	 * 检查秒杀状态
	 */
	@GetMapping("/auth/checkOrder/{skuId}")
	public Result checkOrder(@PathVariable("skuId") Long skuId, HttpServletRequest request) {
		return seckillGoodsService.checkOrder(skuId, AuthContextHolder.getUserId(request));
	}

	/**
	 * 秒杀下单页面数据回显
	 */
	@GetMapping("/auth/trade")
	public Result<HashMap<String, Object>> trade(HttpServletRequest request) {
		String userId = AuthContextHolder.getUserId(request);
		// 收货地址列表
		List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(Long.valueOf(userId));
		// 送货清单
		String orderKey = RedisConst.SECKILL_ORDERS;
		OrderRecode orderRecode = (OrderRecode) redisTemplate.opsForHash().get(orderKey, userId);
		if (ObjectUtils.isEmpty(orderRecode)) {
			return Result.fail(new HashMap<String, Object>()).message("下单失败");
		}
		// 获取到当前秒杀商品
		SeckillGoods seckillGoods = orderRecode.getSeckillGoods();
		ArrayList<OrderDetail> detailArrayList = new ArrayList<>();
		OrderDetail detail = new OrderDetail();
		detail.setSkuName(seckillGoods.getSkuName());
		detail.setSkuId(seckillGoods.getSkuId());
		detail.setImgUrl(seckillGoods.getSkuDefaultImg());
		detail.setOrderPrice(seckillGoods.getCostPrice());
		detail.setSkuNum(orderRecode.getNum());
		detailArrayList.add(detail);

		HashMap<String, Object> map = new HashMap<>();
		map.put("detailArrayList", detailArrayList);
		map.put("userAddressList", userAddressList);
		map.put("totalNum", "1");
		map.put("totalAmount", seckillGoods.getCostPrice());

		return Result.ok(map);
	}

	/**
	 * 提交订单
	 */
	@PostMapping("/auth/submitOrder")
	public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {
		String userId = AuthContextHolder.getUserId(request);
		orderInfo.setUserId(Long.valueOf(userId));

		Long orderId = orderFeignClient.submitOrder(orderInfo);
		if (orderId == null) {
			return Result.fail().message("提交订单失败");
		}

		// 删除缓存信息(预下单)
		redisTemplate.opsForHash().delete(RedisConst.SECKILL_ORDERS, userId);

		// 存储一个真正下单的数据到缓存
		redisTemplate.opsForHash().put(RedisConst.SECKILL_ORDERS_USERS, userId.toString(), orderId.toString());

		return Result.ok(orderId);
	}

}
